package com.acme.bankapp.domain.account;

import java.io.Serializable;

import com.acme.bankapp.exceptions.NotEnoughFundsException;

/**
 * Abstract class for a general presentation of the account.
 *
 * @author S.Zhidkov
 */
public abstract class AbstractAccount implements Account, Serializable {

    protected static final String ERROR_AMOUNT_NEGATIVE = "Amount cannot be smaller than 0!";
    private static final String ERROR_WITHDRAW = "No enough balance to withdraw!";

    protected int id;
	protected double balance;

	/**
	 * Creates account with a certain amount of money.
	 * @param id id of the account
	 * @param amount money
	 */
	public AbstractAccount(final int id, final double amount) {
	    if (amount < 0) {
	        throw new IllegalArgumentException(ERROR_AMOUNT_NEGATIVE);
	    }
	    this.id = id;
		this.balance = amount;
	}

	/**
	 * Method returns balance of the account
	 *
	 * @return balance
	 */
	@Override
    public double getBalance() {
		return balance;
	}

    @Override
    public void deposit(final double amount) throws IllegalArgumentException {
        if (amount < 0) { throw new IllegalArgumentException(ERROR_AMOUNT_NEGATIVE); }
        this.balance += amount;
    }

    @Override
    public void withdraw(final double amount) throws NotEnoughFundsException {
        if (amount < 0) { throw new IllegalArgumentException(ERROR_AMOUNT_NEGATIVE); }
        if (amount <= balance) {
            balance -= amount;
        } else {
            throw new NotEnoughFundsException(ERROR_WITHDRAW);
        }
    }

    @Override
    public double maximumAmountToWithdraw() {
        return balance;
    }

	@Override
    public double decimalValue() {
        return Math.round(balance);
    }

    @Override
    public int hashCode() {
        long bits = Double.doubleToLongBits(balance);
        int result = 17;
        result = 37*result + id;
        result = 37*result + (int) (bits ^ (bits >>> 32));
        return result;
    }

    @Override
	public String toString() {
	    return "[id: " + id + "] [balance: " + balance + "]";
	}

}
